GetArrayPtr
Address = GetArrayPtr(Array(), [SkipHeader=false])
 
Parameters:

    Array() = The Array you wish to query
    [SkipHeader=false] = This flag adds to the array structure header to pointer to not.
Returns:

    Address = The base address of the array structure in memory
 

      The GetArrayPtr function returns the base address of any passed array.

      Arrays are stored as a block of memory. The first bytes are the arrays header. The constant PBArraystruct_size will give you the size of this header structure. While you can read and write to this information if you like, it's best not too change any values in the header. Since, this data is private and is very likely too change in future versions of PlayBASIC, which would break your code.

      Integer & Float arrays are stored as a block of data. Each element is made of either a 32bit integer, or 32bit floating point. So you can peek/poke any value or string even directly into this arrays memory. But be careful not to peek/poke outside the arrays memory though, as if you did that would most likely crash your program.

      Now String & Type arrays are stored differently, each element doesn't hold the string or type data, rather it contains a special integer handle (not a pointer) that represents the string or type structure data in memory. So you can not query these handles directly as this time, since they're part of the runtimes low level services. But, you can swap and move the handles around within the array (or between arrays even), which is perfectly safe as long as you don't lose them or go sticking random data into the array. If you did then your program would either just leak memory or probably crash. So this isn't recommended for those new to programming.

      The main purpose of being able to access an arrays memory directly, is that it allow PlayBASIC arrays to be passed to DLL functions or managed on a lower level by the user. For example, you could access the array directly to shuffle types or strings around.

      The optional SkipHeader parameter can be used to tell the function to return the address of the index/element 0 in the array or the address of the header. So when it's set to 1, the function returns the address of the array and automatically adds the structure size constant for us (PBArrayStruct_size) - This is recommended usage in modern PlayBASIC programs. We don't recommend you use the PBArrayStruct_size in the future.




FACTS:


      * Integer and Float arrays are stored as a block of data. Each element is 32 bits in size.

      * The elements in String & User Defined type variables/Arrays do not store the data directly in the array structure, rather each element is an internal integer handle of the string / type. These handles are NOT currently accessible in PlayBASIC V1.64 (there's no way to get a pointer to the actual data), but you can Peek & Poke the handles just like any other integer. Some care is needed if you do this, but provided you don't alter the handles then you swap and move them around with the array to your hearts content.

      * (OBSOLETE) - All arrays have a private header in PlayBASIC, the size of this header can be determined using the PBArrayStruct_size constant. If your manipulating array data directly, then for future compatibility it's highly recommended that you use PBArrayStruct_size to calculating element zero. This was useful in older editions of PlayBASIC, but we now recommend you use optional parameter in GetArrayPtr() function to calculate this for you.




Mini Tutorial #1:


      Part #1 of this example creates an array called TABLE() with space for 11 elements (0 to 10). It then fills the arrays elements from values from 100 to 110. This is just setting up the demo.

      Part #2 Grabs the Table() base address pointer in memory. Then via directly accessing this memory it displays/maniplates the contents of this array.


  
  
; =============
; Part #1
; =============
  
; Create an Array Called Table()
  Dim Table(10)
  
; Store values in this array
  For lp=0 To 10
     Table(lp)=100+lp
  Next
  
  
; =============
; Part #2
; =============
  
  
; Get the Base Address of this array
  Address=GetArrayPtr(table())
  
; peek the array memory and show the elements
  ShowArray(Address)
  
; manually poke some new values into this arrays memory
  Print "Poking Data Directly Into This Arrays Memory"
  DataAddress=Address+pbarraystruct_size
  For lp=0 To 10
     PokeInt Dataaddress+(lp*4),2000+lp
  Next
  
;Show the array memory again
  ShowArray(Address)
  
  Sync
  WaitKey
  
Function ShowArray(Address)
  Print "Display Array Data"
  DataAddress=Address+pbarraystruct_size
  For lp=0 To 10
     Print PeekInt(Dataaddress+(lp*4))
  Next
EndFunction
  
  
  




This example would output.

  
  Display Array Data
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  Poking Data Directly Into This Arrays Memory
  Display Array Data
  2000
  2001
  2002
  2003
  2004
  2005
  2006
  2007
  2008
  2009
  2010
  





Mini Tutorial #2: (String Array)


      Part #1 of this example creates an array called TABLE$() with space for 11 elements (0 to 10). It then writes two strings in the array, one at element 5 and the other at element 9. It then displays the contents of our array, with some low level information, such as so it shows the not only the Index of each array element, but the HANDLE and the actual STRING as well.

      Part #2 - Now all of this set up is just to create a possible usage situation here, where you might want to run through a string array and pack all the used strings down towards the bottom (index 0). Which is what the RemoveEmptyStrings function in the example bellow does, but this one uses direct array access. Accessing the array memory directly means we can avoid any associated string overheads that come with reading and writing strings.



  
  
; =============
; Part #1 SET UP
; =============
  
  
; Create an Array Called Table$()
  Dim Table$(10)
  
  
; Store some strings in the array
  Table$(5= "Hello"
  
  Table$(9= "World"
  
  
  // Show the array
  ShowArray(Table$())
  
  
; =============
; Part #2  DEMO
; =============
  
  
  // Call function to rip NULL (empty) strings
  // from the array
  RemoveEmptyStrings(Table$())
  
  
  // Show the array after the empty
  // strings have been removed
  ShowArray(Table$())
  
  
  Sync
  WaitKey
  
  
Function RemoveEmptyStrings(THisArray$())
  
  Ptr     =GetArrayPtr(ThisArray$(),true)
  SrcPtr     =Ptr
  DestPtr     =Ptr
  For lp=0 To GetArrayElements(ThisArray$())-1
     ThisString=PeekInt(SrcPtr)
     If ThisString
        
        // move the handle down in the array
        PokeInt DestPtr,THisString
        
        // clear the old one
        PokeInt SrcPtr,0
        
        DestPtr+=4
        
     EndIf
     
     SrcPtr+=4
  Next
  
  INdex=(DestPtr-Ptr)/4
  
EndFunction Index
  
  
  
Function ShowArray(ThisArray$())
  Print "---------------------------------"
  Print "Displaying String Array Data"
  Print "---------------------------------"
  
  Ptr=GetArrayPtr(ThisArray$(),true)
  For lp=0 To GetArrayElements(ThisArray$())-1
     ThisString=PeekInt(ptr)
     If ThisString
        s$=Digits$(lp,2)
        s$+=" Handle="+Digits$(ThisString,6)
        s$+=" String="+ThisArray$(lp)
        Print s$
     EndIf
     // move to the next element in the array
     ptr+=4
  Next
  
  Print ""
EndFunction
  
  



This example would output.


  
  ---------------------------------
  Displaying String Array Data
  ---------------------------------
  05 Handle=000179 String=Hello
  09 Handle=000180 String=World
  
  ---------------------------------
  Displaying String Array Data
  ---------------------------------
  00 Handle=000179 String=Hello
  01 Handle=000180 String=World
  
  
  





 
Related Info: Dim | PBArraystruct_size | PeekByte | PeekFloat | PeekInt | PeekString | PeekWord | PokeByte | PokeFloat | PokeInt | PokeString | PokeWord :
 


(c) Copyright 2002 - 2024 - Kevin Picone - PlayBASIC.com